package cae.gui.history;

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;
import java.util.List;

import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.RowFilter;
import javax.swing.SwingConstants;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableRowSorter;

import cae.gui.util.CaeJDialog;
import cae.logic.CaeMessage;
import cae.logic.destination.CaeDestination;
import cae.logic.destination.CaeDestinatiosManager;
import cae.logic.history.CaeMessageHistory;

public class CaeHistoryDialog extends CaeJDialog implements ActionListener 
{
	private static final long serialVersionUID = 1L;
	private JPanel panel = null;

	private JTable table;
	private JTextField filterText;
	private JTextArea msgText;
	private TableRowSorter<MyTableModel> sorter;
	private List<CaeMessage> messages = CaeMessageHistory.getInstance().getMessages();
	private RowFilter<MyTableModel, Object> filter;

	public CaeHistoryDialog(JFrame frame)
	{
		super(frame, "Historial", true);
		setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);

		panel = new JPanel(new GridBagLayout() );
		getContentPane().add(panel);
		
		// Create a separate form for filterText and statusText
		GridBagConstraints destConst = new GridBagConstraints();
		destConst.insets = new Insets(5,5,5,5);
		destConst.anchor = GridBagConstraints.NORTHEAST;
		destConst.fill = GridBagConstraints.BOTH;

		//Create a table with a sorter.
		MyTableModel model = new MyTableModel();
		sorter = new TableRowSorter<MyTableModel>(model);
		table = new JTable(model);
		table.setRowSorter(sorter);
		table.setPreferredScrollableViewportSize(new Dimension(500, 200));
		table.setFillsViewportHeight(true);

		table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

		//When selection changes, provide user with row numbers for
		//both view and model.
		table.getSelectionModel().addListSelectionListener(
				new ListSelectionListener() {
					public void valueChanged(ListSelectionEvent event) {
						int viewRow = table.getSelectedRow();
						if (viewRow < 0) {
							//Selection got filtered away.
							msgText.setText("");
						} else {
							int row = sorter.convertRowIndexToModel(viewRow);
							msgText.setText(messages.get(row).getText());
						}
					}
				}
		);


		//Create the scroll pane and add the table to it.
		JScrollPane scrollPane = new JScrollPane(table);

		destConst.gridx = 0;
		destConst.gridy = 0;
		destConst.weighty = 100;
		destConst.gridwidth = 3;
		//Add the scroll pane to this panel.
		panel.add(scrollPane, destConst);

		
		
		
		JLabel l1 = new JLabel("Buscar: ", SwingConstants.TRAILING);
		destConst.gridx = 0;
		destConst.gridy = 1;
		destConst.gridwidth = 1;
		destConst.weighty = 0;
		panel.add(l1, destConst);
		filterText = new JTextField();
		//Whenever filterText changes, invoke newFilter.
		filterText.getDocument().addDocumentListener(
				new DocumentListener() {
					public void changedUpdate(DocumentEvent e) {
						newFilter();
					}
					public void insertUpdate(DocumentEvent e) {
						newFilter();
					}
					public void removeUpdate(DocumentEvent e) {
						newFilter();
					}
				});
		l1.setLabelFor(filterText);
		destConst.weightx = 100;
		destConst.gridx = 1;
		destConst.gridy = 1;
		panel.add(filterText, destConst);
		JLabel l2 = new JLabel("Mensaje:", SwingConstants.TRAILING);
		destConst.weightx = 0;
		destConst.gridx = 0;
		destConst.gridy = 2;
		panel.add(l2, destConst);
		msgText = new JTextArea(10, 40);
		msgText.setEditable(false);
		msgText.setLineWrap(true);
		//msgText.setEnabled(false);
		l2.setLabelFor(msgText);
		destConst.gridx = 1;
		destConst.gridy = 2;
		destConst.weightx = 100;
		panel.add(new JScrollPane(msgText), destConst);

		pack();

		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		setLocation(screenSize.width / 4, screenSize.height /4);

		//setResizable(false);
		setAlwaysOnTop(true);
		setVisible(true);

		// TODO FOCO
		//FocusManager.getCurrentManager().

	}

	/** 
	 * Update the row filter regular expression from the expression in
	 * the text box.
	 */
	private void newFilter()
	{
		//If current expression doesn't parse, don't update.
		try {
			filter = RowFilter.regexFilter(filterText.getText(), 1);
		} catch (java.util.regex.PatternSyntaxException e) {
			return;
		}
		sorter.setRowFilter(filter);
	}




	class MyTableModel extends AbstractTableModel 
	{
		private static final long serialVersionUID = 1L;
		private String[] columnNames = {"Usuario", "Mensaje", "Fecha"};

		public int getColumnCount() {
			return columnNames.length;
		}

		public int getRowCount() {
			return messages.size();
		}

		public String getColumnName(int col) {
			return columnNames[col];
		}

		public Object getValueAt(int row, int col) 
		{
			Object o = null;
			switch (col) {
			case 0:
				CaeDestination d = CaeDestinatiosManager.getInstance().getDestination(messages.get(row).getFrom());
				if(d != null)
					o = d.getAlias();
				else
					o = messages.get(row).getFrom();
				break;
			case 1:
				o = messages.get(row).getText();
				break;
			case 2:
				o = messages.get(row).getDate();
				break;
			}
			return o;
		}

		@SuppressWarnings("unchecked")
		public Class getColumnClass(int c) 
		{
			switch (c) {
			case 0:
				return String.class;
			case 1:
				return String.class;
			case 2:
				return Date.class;
			}
			return null;
		}

		public boolean isCellEditable(int row, int col) {
			return false;
		}

		public void setValueAt(Object value, int row, int col) {
			// NO APLICA
		}
	}

	public void actionPerformed(ActionEvent e)
	{
		setVisible(false);
	}
}
